using System;
using System.ComponentModel;
using System.Drawing;
using System.Design;
 using System.Drawing.Design;
using System.Globalization;
using System.Security.Permissions;
using System.Text;
using System.Web;
using System.Web.UI;
using PickGold.Charting.Design;
using PickGold.Charting.Utilities;

namespace PickGold.Charting
{
	[SRDescription("DescriptionAttributeDataPoint_DataPoint")]
	[TypeConverter(typeof(Editors.DataPointConverter))]
	[DefaultProperty("YValues")]
	[AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
	[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
	public class DataPoint : DataPointCustomProperties
	{
		private double _xValue;
		private double[] _yValue;
		internal PointF positionRel;

		public DataPoint() : base(null, true)
		{
			this._yValue = new double[1];
			this.positionRel = PointF.Empty;
			this._yValue = new double[1];
		}

		public DataPoint(Series series) : base(series, true)
		{
			this._yValue = new double[1];
			this.positionRel = PointF.Empty;
			this._yValue = new double[series.YValuesPerPoint];
			this._xValue = 0.0;
		}

		public DataPoint(double xValue, double yValue) : base(null, true)
		{
			this._yValue = new double[1];
			this.positionRel = PointF.Empty;
			this._yValue = new double[] { yValue };
			this._xValue = xValue;
		}

		public DataPoint(double xValue, double[] yValues) : base(null, true)
		{
			this._yValue = new double[1];
			this.positionRel = PointF.Empty;
			this._yValue = yValues;
			this._xValue = xValue;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public DataPoint(double xValue, string yValues) : base(null, true)
		{
			this._yValue = new double[1];
			this.positionRel = PointF.Empty;
			string[] strArray = yValues.Split(new char[] { ',' });
			this._yValue = new double[strArray.Length];
			for (int i = 0; i < strArray.Length; i++)
			{
				this._yValue[i] = CommonElements.ParseDouble(strArray[i], true);
			}
			this._xValue = xValue;
		}

		public DataPoint Clone()
		{
			DataPoint point = new DataPoint();
			point.series = null;
			point.pointCustomProperties = base.pointCustomProperties;
			point._xValue = this.XValue;
			point._yValue = new double[this._yValue.Length];
			this._yValue.CopyTo(point._yValue, 0);
			point.tempColorIsSet = base.tempColorIsSet;
			point.isEmptyPoint = base.isEmptyPoint;
			foreach (object obj2 in base.properties.Keys)
			{
				point.properties.Add(obj2, base.properties[obj2]);
			}
			return point;
		}

		private double ConvertValue(object value)
		{
			if (value == null)
			{
				return 0.0;
			}
			if (value is double)
			{
				return (double)value;
			}
			if (value is float)
			{
				return (double)((float)value);
			}
			if (value is decimal)
			{
				return (double)((decimal)value);
			}
			if (value is int)
			{
				return (double)((int)value);
			}
			if (value is uint)
			{
				return (double)((uint)value);
			}
			if (value is long)
			{
				return (double)((long)value);
			}
			if (value is ulong)
			{
				return (double)((ulong)value);
			}
			if (value is byte)
			{
				return (double)((byte)value);
			}
			if (value is sbyte)
			{
				return (double)((sbyte)value);
			}
			if (value is bool)
			{
				if (!((bool)value))
				{
					return 0.0;
				}
				return 1.0;
			}
			return CommonElements.ParseDouble(value.ToString());
		}

		public double GetValueByName(string valueName)
		{
			if (valueName == null)
			{
				throw new ArgumentNullException("valueName");
			}
			valueName = valueName.ToUpper(CultureInfo.InvariantCulture);
			if (string.Compare(valueName, "X", StringComparison.Ordinal) == 0)
			{
				return this.XValue;
			}
			if (!valueName.StartsWith("Y", StringComparison.Ordinal))
			{
				throw new ArgumentException(SR.ExceptionDataPointValueNameInvalid, "valueName");
			}
			if (valueName.Length == 1)
			{
				return this.YValues[0];
			}
			int index = 0;
			try
			{
				index = int.Parse(valueName.Substring(1), CultureInfo.InvariantCulture) - 1;
			}
			catch (Exception)
			{
				throw new ArgumentException(SR.ExceptionDataPointValueNameInvalid, "valueName");
			}
			if (index < 0)
			{
				throw new ArgumentException(SR.ExceptionDataPointValueNameYIndexIsNotPositive, "valueName");
			}
			if (index >= this.YValues.Length)
			{
				throw new ArgumentException(SR.ExceptionDataPointValueNameYIndexOutOfRange, "valueName");
			}
			return this.YValues[index];
		}

		private string RemoveOneKeyword(string strOriginal, string keyword, string strToReplace)
		{
			string format = strOriginal;
			int startIndex = -1;
			while ((startIndex = format.IndexOf(keyword, StringComparison.Ordinal)) != -1)
			{
				int num2 = startIndex + keyword.Length;
				if ((format.Length > num2) && (format[num2] == '{'))
				{
					int index = format.IndexOf('}', num2);
					if (index == -1)
					{
						throw new InvalidOperationException(SR.ExceptionDataSeriesKeywordFormatInvalid(format));
					}
					num2 = index + 1;
				}
				format = format.Remove(startIndex, num2 - startIndex);
				if (!string.IsNullOrEmpty(strToReplace))
				{
					format = format.Insert(startIndex, strToReplace);
				}
			}
			return format;
		}

		internal static string ReplaceCustomPropertyKeyword(string originalString, DataPointCustomProperties properties)
		{
			string str = originalString;
			int startIndex = -1;
			while ((startIndex = str.IndexOf("#CUSTOMPROPERTY", StringComparison.Ordinal)) >= 0)
			{
				string customProperty = string.Empty;
				string name = string.Empty;
				int num2 = startIndex + "#CUSTOMPROPERTY".Length;
				if ((str.Length > num2) && (str[num2] == '('))
				{
					num2++;
					int num3 = num2;
					int index = str.IndexOf(')', num2);
					if (index >= num2)
					{
						num2 = index + 1;
						name = str.Substring(num3, (num2 - num3) - 1);
						if (properties.IsCustomPropertySet(name))
						{
							customProperty = properties.GetCustomProperty(name);
						}
						else
						{
							DataPoint point = properties as DataPoint;
							if (((point != null) && (point.series != null)) && point.series.IsCustomPropertySet(name))
							{
								customProperty = point.series.GetCustomProperty(name);
							}
						}
					}
				}
				str = str.Remove(startIndex, num2 - startIndex).Insert(startIndex, customProperty);
			}
			return str;
		}

		internal override string ReplaceKeywords(string strOriginal)
		{
			if ((strOriginal == null) || (strOriginal.Length == 0))
			{
				return strOriginal;
			}
			string str = strOriginal;
			str = ReplaceCustomPropertyKeyword(str.Replace(@"\n", "\n").Replace("#LABEL", this.Label).Replace("#LEGENDTEXT", base.LegendText).Replace("#AXISLABEL", this.AxisLabel), this);
			if (base.series == null)
			{
				return str;
			}
			str = str.Replace("#INDEX", base.series.Points.IndexOf(this).ToString(CultureInfo.InvariantCulture));
			str = base.series.ReplaceKeywords(str);
			str = base.series.ReplaceOneKeyword(base.Chart, this, base.Tag, ChartElementType.DataPoint, str, "#PERCENT", (double)(this.YValues[0] / base.series.GetTotalYValue()), ChartValueType.Double, "P");
			if (base.series.XValueType == ChartValueType.String)
			{
				str = str.Replace("#VALX", this.AxisLabel);
			}
			else
			{
				str = base.series.ReplaceOneKeyword(base.Chart, this, base.Tag, ChartElementType.DataPoint, str, "#VALX", this.XValue, base.series.XValueType, "");
			}
			for (int i = this.YValues.Length; i <= 7; i++)
			{
				str = this.RemoveOneKeyword(str, "#VALY" + i + 1, SR.FormatErrorString);
			}
			for (int j = 1; j <= this.YValues.Length; j++)
			{
				str = base.series.ReplaceOneKeyword(base.Chart, this, base.Tag, ChartElementType.DataPoint, str, "#VALY" + j, this.YValues[j - 1], base.series.YValueType, "");
			}
			str = base.series.ReplaceOneKeyword(base.Chart, this, base.Tag, ChartElementType.DataPoint, str, "#VALY", this.YValues[0], base.series.YValueType, "");
			return base.series.ReplaceOneKeyword(base.Chart, this, base.Tag, ChartElementType.DataPoint, str, "#VAL", this.YValues[0], base.series.YValueType, "");
		}

		internal void ResizeYValueArray(int newSize)
		{
			double[] numArray = new double[newSize];
			if (this._yValue != null)
			{
				for (int i = 0; i < ((this._yValue.Length < newSize) ? this._yValue.Length : newSize); i++)
				{
					numArray[i] = this._yValue[i];
				}
			}
			this._yValue = numArray;
		}

		internal void SetPointCustomProperty(object obj, string propertyName, string format)
		{
			string str = obj as string;
			if (str == null)
			{
				double naN = double.NaN;
				ChartValueType auto = ChartValueType.Auto;
				if (obj is DateTime)
				{
					naN = ((DateTime)obj).ToOADate();
					auto = ChartValueType.Date;
				}
				else
				{
					naN = this.ConvertValue(obj);
				}
				if (!double.IsNaN(naN))
				{
					try
					{
						str = ValueConverter.FormatValue(base.Chart, this, base.Tag, naN, format, auto, ChartElementType.DataPoint);
					}
					catch (FormatException)
					{
						str = obj.ToString();
					}
				}
				else
				{
					str = obj.ToString();
				}
			}
			if (str.Length > 0)
			{
				if (string.Compare(propertyName, "AxisLabel", StringComparison.OrdinalIgnoreCase) == 0)
				{
					this.AxisLabel = str;
				}
				else if (string.Compare(propertyName, "Tooltip", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.ToolTip = str;
				}
				else if (string.Compare(propertyName, "Url", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.Url = str;
				}
				else if (string.Compare(propertyName, "PostBackValue", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.PostBackValue = str;
				}
				else if (string.Compare(propertyName, "LabelUrl", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.LabelUrl = str;
				}
				else if (string.Compare(propertyName, "LabelPostBackValue", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.LabelPostBackValue = str;
				}
				else if (string.Compare(propertyName, "LegendUrl", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.LegendUrl = str;
				}
				else if (string.Compare(propertyName, "LegendPostBackValue", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.LegendPostBackValue = str;
				}
				else if (string.Compare(propertyName, "Label", StringComparison.OrdinalIgnoreCase) == 0)
				{
					this.Label = str;
				}
				else if (string.Compare(propertyName, "LegendTooltip", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.LegendToolTip = str;
				}
				else if (string.Compare(propertyName, "LegendText", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.LegendText = str;
				}
				else if (string.Compare(propertyName, "LabelToolTip", StringComparison.OrdinalIgnoreCase) == 0)
				{
					base.LabelToolTip = str;
				}
				else
				{
					base[propertyName] = str;
				}
			}
		}

		public void SetValueXY(object xValue, params object[] yValue)
		{
			if (xValue == null)
			{
				throw new ArgumentNullException("xValue");
			}
			this.SetValueY(yValue);
			Type type = xValue.GetType();
			if (base.series != null)
			{
				base.series.CheckSupportedTypes(type);
			}
			if (type == typeof(string))
			{
				this.AxisLabel = (string)xValue;
			}
			else if (type == typeof(DateTime))
			{
				this._xValue = ((DateTime)xValue).ToOADate();
			}
			else
			{
				this._xValue = this.ConvertValue(xValue);
			}
			if ((base.series != null) && (xValue is DateTime))
			{
				if (base.series.XValueType == ChartValueType.Date)
				{
					DateTime time4 = (DateTime)xValue;
					DateTime time5 = (DateTime)xValue;
					DateTime time6 = (DateTime)xValue;
					this._xValue = new DateTime(time4.Year, time5.Month, time6.Day, 0, 0, 0, 0).ToOADate();
				}
				else if (base.series.XValueType == ChartValueType.Time)
				{
					DateTime time7 = (DateTime)xValue;
					DateTime time8 = (DateTime)xValue;
					DateTime time9 = (DateTime)xValue;
					DateTime time10 = (DateTime)xValue;
					this._xValue = new DateTime(0x76b, 12, 30, time7.Hour, time8.Minute, time9.Second, time10.Millisecond).ToOADate();
				}
			}
			bool flag = false;
			foreach (double num in this._yValue)
			{
				if (double.IsNaN(num))
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				this.IsEmpty = true;
				for (int i = 0; i < this._yValue.Length; i++)
				{
					this._yValue[i] = 0.0;
				}
			}
		}

		public void SetValueY(params object[] yValue)
		{
			if (yValue == null)
			{
				throw new ArgumentNullException("yValue");
			}
			if ((yValue.Length == 0) || ((base.series != null) && (yValue.Length > base.series.YValuesPerPoint)))
			{
				throw new ArgumentOutOfRangeException("yValue", SR.ExceptionDataPointYValuesSettingCountMismatch(base.series.YValuesPerPoint.ToString(CultureInfo.InvariantCulture)));
			}
			for (int i = 0; i < yValue.Length; i++)
			{
				if ((yValue[i] == null) || (yValue[i] is DBNull))
				{
					yValue[i] = 0.0;
					if (i == 0)
					{
						this.IsEmpty = true;
					}
				}
			}
			Type type = yValue[0].GetType();
			if (base.series != null)
			{
				base.series.CheckSupportedTypes(type);
			}
			if (this._yValue.Length < yValue.Length)
			{
				this._yValue = new double[yValue.Length];
			}
			if (type == typeof(string))
			{
				try
				{
					for (int j = 0; j < yValue.Length; j++)
					{
						this._yValue[j] = CommonElements.ParseDouble((string)yValue[j]);
					}
				}
				catch
				{
					if (((base.Common == null) || (base.Common.ChartPicture == null)) || !base.Common.ChartPicture.SuppressExceptions)
					{
						throw new ArgumentException(SR.ExceptionDataPointYValueStringFormat);
					}
					this.IsEmpty = true;
					for (int k = 0; k < yValue.Length; k++)
					{
						yValue[k] = 0.0;
					}
				}
			}
			else if (type == typeof(DateTime))
			{
				for (int m = 0; m < yValue.Length; m++)
				{
					if ((yValue[m] == null) || ((yValue[m] is double) && (((double)yValue[m]) == 0.0)))
					{
						this._yValue[m] = DateTime.Now.ToOADate();
					}
					else
					{
						this._yValue[m] = ((DateTime)yValue[m]).ToOADate();
					}
				}
			}
			else
			{
				for (int n = 0; n < yValue.Length; n++)
				{
					this._yValue[n] = this.ConvertValue(yValue[n]);
				}
			}
			if (base.series != null)
			{
				for (int num6 = 0; num6 < yValue.Length; num6++)
				{
					if ((yValue[num6] == null) || ((yValue[num6] is double) && (((double)yValue[num6]) == 0.0)))
					{
						if (base.series.YValueType == ChartValueType.Date)
						{
							this._yValue[num6] = Math.Floor(this._yValue[num6]);
						}
						else if (base.series.YValueType == ChartValueType.Time)
						{
							this._yValue[num6] = this._xValue - Math.Floor(this._yValue[num6]);
						}
					}
					else if (base.series.YValueType == ChartValueType.Date)
					{
						DateTime time;
						if (yValue[num6] is DateTime)
						{
							time = (DateTime)yValue[num6];
						}
						else if (yValue[num6] is double)
						{
							time = DateTime.FromOADate((double)yValue[num6]);
						}
						else
						{
							time = Convert.ToDateTime(yValue[num6], CultureInfo.InvariantCulture);
						}
						this._yValue[num6] = new DateTime(time.Year, time.Month, time.Day, 0, 0, 0, 0).ToOADate();
					}
					else if (base.series.YValueType == ChartValueType.Time)
					{
						DateTime time3;
						if (yValue[num6] is DateTime)
						{
							time3 = (DateTime)yValue[num6];
						}
						if (yValue[num6] is double)
						{
							time3 = DateTime.FromOADate((double)yValue[num6]);
						}
						else
						{
							time3 = Convert.ToDateTime(yValue[num6], CultureInfo.InvariantCulture);
						}
						this._yValue[num6] = new DateTime(0x76b, 12, 30, time3.Hour, time3.Minute, time3.Second, time3.Millisecond).ToOADate();
					}
				}
			}
		}

		internal override string ToStringInternal()
		{
			StringBuilder builder = new StringBuilder();
			builder.AppendFormat(CultureInfo.CurrentCulture, "{{X={0}, ", new object[] { this.XValue });
			if (this.YValues.Length == 1)
			{
				builder.AppendFormat(CultureInfo.CurrentCulture, "Y={0}", new object[] { this.YValues[0] });
			}
			else
			{
				builder.Append("Y={");
				for (int i = 0; i < this.YValues.Length; i++)
				{
					if (i == 0)
					{
						builder.AppendFormat(CultureInfo.CurrentCulture, "{0}", new object[] { this.YValues[i] });
					}
					else
					{
						builder.AppendFormat(CultureInfo.CurrentCulture, ", {0}", new object[] { this.YValues[i] });
					}
				}
				builder.Append("}");
			}
			builder.Append("}");
			return builder.ToString();
		}

		[DefaultValue(false)]
		[SRDescription("DescriptionAttributeDataPoint_Empty")]
		[SRCategory("CategoryAttributeData")]
		[Bindable(true)]
		[PersistenceMode(PersistenceMode.Attribute)]
		public bool IsEmpty
		{
			get
			{
				return base.isEmptyPoint;
			}
			set
			{
				base.isEmptyPoint = value;
				base.Invalidate(true);
			}
		}

		[SRDescription("DescriptionAttributeDataPoint_Name")]
		[Bindable(true)]
		[Browsable(false)]
		[SRCategory("CategoryAttributeData")]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[SerializationVisibility(SerializationVisibility.Hidden)]
		public override string Name
		{
			get
			{
				return "DataPoint";
			}
			set
			{
			}
		}

		[Bindable(true)]
		[SRCategory("CategoryAttributeData")]
		[SRDescription("DescriptionAttributeDataPoint_XValue")]
		[TypeConverter(typeof(DataPointValueConverter))]
		[DefaultValue(typeof(double), "0.0")]
		[PersistenceMode(PersistenceMode.Attribute)]
		public double XValue
		{
			get
			{
				return this._xValue;
			}
			set
			{
				this._xValue = value;
				base.Invalidate(false);
			}
		}

		[PersistenceMode(PersistenceMode.Attribute)]
		[Bindable(true)]
		[SRCategory("CategoryAttributeData")]
		[SRDescription("DescriptionAttributeDataPoint_YValues")]
		[Editor(typeof(UITypeEditor), typeof(UITypeEditor))]
		[SerializationVisibility(SerializationVisibility.Attribute)]
		[TypeConverter(typeof(DoubleArrayConverter))]
		[RefreshProperties(RefreshProperties.All)]
		public double[] YValues
		{
			get
			{
				return this._yValue;
			}
			set
			{
				if (value == null)
				{
					for (int i = 0; i < this._yValue.Length; i++)
					{
						this._yValue[i] = 0.0;
					}
				}
				else
				{
					this._yValue = value;
				}
				base.Invalidate(false);
			}
		}
	}
}

